<template>
  <div class="sortable-inputs">
    <div class="items" ref="items">
      <div v-for="(item, idx) in datas" :key="(item as string)" class="item">
        <label v-if="idx != datas.length - 1" class="remove clickable"
          ><i class="icon iconfont-zui icon-zui-remove" @click="onRemove(idx, item)"></i
        ></label>
        <label v-if="showSequence" class="sequence">{{ idx + 1 }}.</label>
        <zui-input
          class="input"
          clear
          placeholder="点击输入"
          text-align="left"
          :show-border="false"
          v-model="datas[idx]['text']"
          padding="12px 8px"
          clearable
        />
        <label v-if="idx != datas.length - 1" class="sort clickable">
          <i class="icon iconfont-zui icon-zui-sort"></i
        ></label>
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">
import Sortable from 'sortablejs'
import { nextTick, ref, watch, CSSProperties } from 'vue'

const emit = defineEmits(['update:modelValue'])

const props = defineProps({
  modelValue: { default: () => [], type: Array },
  showSequence: Boolean
})

//***** 数据 *****/
const datas = ref([...props.modelValue, { text: '' }])
watch(
  () => props.modelValue,
  (value) => {
    datas.value = [...value, { text: '' }]
  }
)
//***** 排序 *****/
const items = ref()

nextTick(() => {
  Sortable.create(items.value, {
    handle: '.sort',
    onEnd: function (evt) {
      // 元素放到目标位置，其余元素（拖动开始到拖动结束位置直接的元素）向上顶或向下压
      const { oldIndex: startIndex, newIndex: endIndex } = evt
      const dragData = datas.value[startIndex]
      datas.value.splice(startIndex, 1)
      datas.value.splice(endIndex, 0, dragData)
    }
  })
})

//***** 保证末尾有一个空元素 *****/
watch(
  datas,
  (newValue: any) => {
    const lastData = newValue[newValue.length - 1]
    if (lastData.text) {
      datas.value.push({ text: '' })
    }
    if (newValue.length > 1) {
      const penultData = newValue[newValue.length - 2]
      if (!penultData.text) {
        datas.value.pop()
      }
    }
  },
  { deep: true }
)

//***** 移除 *****/
function onRemove(idx, item) {
  datas.value.splice(idx, 1)
}

//***** 监听条目变化 发送更新事件*****/
watch(
  datas,
  (newValue) => {
    const resolvedValue = newValue.slice(0, newValue.length - 1)
    if (JSON.stringify(resolvedValue) == JSON.stringify(props.modelValue)) {
      return
    }

    emit('update:modelValue', resolvedValue)
  },
  { deep: true }
)
</script>
<style lang="scss" scoped>
.sortable-inputs {
  width: 100%;
  .item {
    position: relative;
    display: flex;
    align-items: center;
    background-color: #ffffff;
    &.item:not(:last-child)::after {
      position: absolute;
      bottom: 0;
      left: 20px;
      height: 0.5px;
      width: calc(100% - 20px);
      content: '';
      display: inline-block;
      background-color: var(--color-divider-light);
    }
    &.item:not(:first-child):last-child {
      padding-left: 22px;
    }
    .remove {
      margin-right: 8px;
      width: 16px;
      .icon {
        color: var(--zui-color-red);
      }
    }
    .sequence {
      min-width: 20px;
      color: var(--zui-color-text-placeholder);
    }
    .input {
      padding: 0 16px 0 0;
    }
    .sort {
      color: var(--zui-color-primary);
      .icon {
        font-size: 20px;
      }
    }
  }
}
</style>
